﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MeTalker.Aide;
using MeTalker.SDK.Core;
using MeTalker.Aide.data;
using MeTalker.Aide.Forms;
using MeTalker.Window.SDK.Core;

namespace MeTalker.Aide.Forms
{

    internal delegate void BodyMessageHandler(object sender, string msg, string user);

    internal partial class TalkerForm : TalkerBase, IWorkMode
    {
        public IWork Work { get; set; }
        internal List<IntPtr> hWnds;
        OrderForm orderForm;
        internal BodyHandler BorBodyHandler { get; set; }
        BodyHandler SaveHandler;
        Timer TopTimer;

        TalkerTip tip;
        void HideWin()
        {
            State = TalkerState.Hidden;
            this.Visible = false;
            if (orderForm != null)
                orderForm.Visible = false;
            tip = new TalkerTip(this);
            tip.Show();
        }

        void ShowWin()
        {
            State = TalkerState.Display;
            this.Visible = true;
            if (orderForm != null)
                orderForm.Visible = true;
            helper.SetForegroundMainWindow();
        }


        #region 构造
        public TalkerForm(ProcInfo proc, IWork work)
            : base(proc)
        {
            InitializeComponent();
            this.Shown += new EventHandler(TalkerForm_Shown);
            this.ResizeBegin += new EventHandler(TalkerForm_ResizeBegin);
            this.Resize += new EventHandler(TalkerForm_Resize);
            WorkProcess = proc;
            this.Work = work;
            TopTimer = new Timer();
            TopTimer.Tick += new EventHandler(TopTimer_Tick);
            //pictureBox2.Image = new Bitmap(FileFactory.BaseDirectory+ "icons/iconx.gif");
            pictureBox1.Image = new Bitmap(FileFactory.BaseDirectory + "icons/title.PNG");
            SaveHandler = new BodyHandler(SaveSendHandler);
            MessageBodyHandler = new MeTalker.Aide.BodyHandler(BodyHandler);
            orderForm = new OrderForm(this);
            this.Load += new EventHandler(TalkerForm_Load);
            this.FormClosing += new FormClosingEventHandler(TalkerForm_FormClosing);
            messageContorl.MeMouseClick += new MouseEventHandler(messageContorl_MeMouseClick);
            ((IWorkMode)this).InitData();
            if (mainHandler == IntPtr.Zero)
            {
                this.Close();
                return;
            }
            hWnds = new List<IntPtr>() {  };
        }

        void TalkerForm_Resize(object sender, EventArgs e)
        {
            if (this.Width>UtilHelper.MAX_MSG_WIDTH) {
                UtilHelper.MAX_MSG_WIDTH = this.Width;
            }
            if (this.Width < UtilHelper.MIN_MSG_WIDTH) {
                this.Width = UtilHelper.MIN_MSG_WIDTH;
            }
            isResize = false;
        }
        bool isResize = false;
        void TalkerForm_ResizeBegin(object sender, EventArgs e)
        {
            isResize = true;
        }

        internal readonly static int WM_NCHITTEST = 0x84;
        internal readonly static IntPtr HTCLIENT = (IntPtr)0x1;
        internal readonly static IntPtr HTCAPTION = (IntPtr)0x2;
        internal readonly static int WM_NCLBUTTONDBLCLK = 0x00A3;
        int RefreshTimout = 500;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x84)
            {
                base.WndProc(ref m);
                Point p = new Point(((int)m.LParam) & 0xffff, (((int)m.LParam) >> 0x10) & 0xffff);
                p = base.PointToClient(p);
                if (p.X >= (base.ClientSize.Width - 5))
                {
                    if (p.Y <= 5)
                    {
                        m.Result = (IntPtr)14;
                    }
                    else if (p.Y >= (base.ClientSize.Height - 5))
                    {
                        m.Result = (IntPtr)0x11;
                    }
                    else
                    {
                        m.Result = (IntPtr)11;
                    }
                }
                else if (p.Y >= (base.ClientSize.Height - 5))
                {
                    m.Result = (IntPtr)15;
                }
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        void TalkerForm_Shown(object sender, EventArgs e)
        {
            this.TopMost = false;
            orderForm.TopMost = false;
        }

        #region 继承

       void IWork.Refresh() { }

        public WorkModeCallBack WorkCallback { get; set; }

       public ProcInfo WorkProcess { get; set; }

       void IWorkMode.InitView()
        {

        }
       #region 初始化数据
       void IWorkMode.InitData()
        {
            try
            {

                if (messageContorl != null)
                {
                    messageContorl.TabControl.TabPages.Clear();
                }
                if (DataFactory.Messages != null)
                {
                    foreach (var root in DataFactory.Messages.Nodes)
                    {
                        if (root.SubNode != null && root.SubNode.Count > 0 && root.SubNode[0].SubNode != null && root.SubNode[0].SubNode.Count > 0)
                        {
                            MessageContorl messageControl1 = new MessageContorl();
                            messageControl1.Dock = DockStyle.Fill;
                            MeTabControlPage tab2 = new MeTabControlPage();
                            tab2.Text = root.Text;
                            tab2.Controls.Add(messageControl1);
                            this.messageContorl.TabControl.TabPages.Add(tab2);

                            foreach (var rootNode in root.SubNode)
                            {
                                if (rootNode.SubNode.Count > 0)
                                {
                                    MeTalker.Aide.Forms.MeTabPage tab1 = new MeTalker.Aide.Forms.MeTabPage();
                                    tab1.TreeViewEvent += new TreeViewEventHandler(TreeViewNodeSelect);
                                    tab1.TreeNodeMouseClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseClick);
                                    tab1.TreeNodeMouseDoubleClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseDoubleClick);
                                    tab1.BlankMouseClickEvent += new MouseEventHandler(Blank_MouseDown);
                                    tab1.Text = rootNode.Text;
                                    NodeFactory.SetListNode(rootNode, tab1.TreeViewData);
                                    messageControl1.TabControl.TabPages.Add(tab1);
                                }
                            }
                            //对总和再生成一颗树
                            {
                                MeTalker.Aide.Forms.MeTabPage tab3 = new MeTalker.Aide.Forms.MeTabPage();
                                tab3.TreeViewEvent += new TreeViewEventHandler(TreeViewNodeSelect);
                                tab3.TreeNodeMouseClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseClick);
                                tab3.TreeNodeMouseDoubleClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseDoubleClick);
                                tab3.BlankMouseClickEvent += new MouseEventHandler(Blank_MouseDown);
                                tab3.Text = "*" + root.Text;
                                NodeFactory.SetNode(root, tab3.TreeViewData);
                                messageControl1.TabControl.TabPages.Add(tab3);
                            }
                        }
                        else
                        {
                            MeTalker.Aide.Forms.MeTabPage tab1 = new MeTalker.Aide.Forms.MeTabPage();
                            tab1.TreeViewEvent += new TreeViewEventHandler(TreeViewNodeSelect);
                            tab1.TreeNodeMouseClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseClick);
                            tab1.TreeNodeMouseDoubleClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseDoubleClick);
                            tab1.BlankMouseClickEvent += new MouseEventHandler(Blank_MouseDown);
                            tab1.Text = root.Text;
                            NodeFactory.SetNode(root, tab1.TreeViewData);
                            this.messageContorl.TabControl.TabPages.Add(tab1);
                        }
                    }

                    ///所有短语
                    {
                        MeTalker.Aide.Forms.MeTabPage taball = new MeTalker.Aide.Forms.MeTabPage();
                        taball.TreeViewEvent += new TreeViewEventHandler(TreeViewNodeSelect);
                        taball.TreeNodeMouseClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseClick);
                        taball.TreeNodeMouseDoubleClickEvent += new TreeNodeMouseClickEventHandler(NodeMouseDoubleClick);
                        taball.BlankMouseClickEvent += new MouseEventHandler(Blank_MouseDown);
                        taball.Text = "所有 *";
                        //NodeFactory.SetNode(root, taball.TreeViewData);
                        NodeFactory.ToTreeView(DataFactory.Messages.Nodes, taball.TreeViewData);
                        this.messageContorl.TabControl.TabPages.Add(taball);
                    }
                }
            }
            catch { }
        }
       
        MeTabControlPage SetCollectionTab(List<Node> nodes)
        {
            MessageContorl messageControl = new MessageContorl();
            messageControl.Dock = DockStyle.Fill;
            MeTabControlPage tab2 = new MeTabControlPage();
            tab2.Text = DataFactory.NodeLists.Title;
            tab2.Controls.Add(messageControl);
            this.messageContorl.TabControl.TabPages.Add(tab2);
            return tab2;
        }
        
        void Blank_MouseDown(object sender, MouseEventArgs e)
        {
            Work.Refresh();
        }

        void NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {
                string msg = e.Node.Text;
                int leftIndex = msg.IndexOf(UtilHelper.FAST_LEFT_SYMBOL);
                int rightIndex = msg.IndexOf(UtilHelper.FAST_RIGHT_SYMBOL);
                if (leftIndex >= 0 && rightIndex > 0)
                {
                    msg = msg.Substring(rightIndex + 1, msg.Length - (rightIndex + 1)).Trim();
                }

                
                SetText(msg);
                //KeysetControl.SendMessage(helper.HandleMessageBody, msg);
                //MeTalker.Window.SDK.Core.KeysetControl.SendMessage(helper.HandleMessageBody, 0xb1, 0, -1);

                //EndSend(helper.HandleMessageBody, msg, false);
                //for (int i = 0; i < 100; i++)
                //{
                //    if (helper.HandleWinForm == WindowControl.GetForegroundWindow())
                //    {
                //        break;
                //    }
                //    WindowControl.SetForegroundWindow(helper.HandleWinForm);
                //    System.Threading.Thread.Sleep(50);
                //}
                //MeTalker.Window.SDK.Core.KeysetControl.SendMessage(helper.HandleMessageBody, 7, 0, 0);
                
                //System.Threading.Thread.Sleep(100);
                //Console.WriteLine("发送");
                //g(msg);// b(helper.HandleMessageBody, msg, true);
                //MeTalker.Window.SDK.Core.KeysetControl.SendMessage(helper.HandleMessageBody, 0x100, 0xE5, 0);

                
            }
            catch { }
        }

       

        void NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {
                string msg = e.Node.Text;
                int leftIndex = msg.IndexOf(UtilHelper.FAST_LEFT_SYMBOL);
                int rightIndex = msg.IndexOf(UtilHelper.FAST_RIGHT_SYMBOL);
                if (leftIndex >= 0 && rightIndex > 0)
                {
                    msg = msg.Substring(rightIndex + 1, msg.Length - (rightIndex + 1));
                }
                if (helper != null)
                    SendText(msg);
               
            }
            catch { }
        }
       

        void TreeViewNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
            }
            catch { }
        }

        #endregion



         bool IWork.Start()
        {
            this.Show();
            return true;
        }

         void IWork.Stop()
        {
            this.Close();
        }

        #endregion

        void messageContorl_MeMouseClick(object sender, MouseEventArgs e)
        {
            Console.WriteLine("messageContorl_MeMouseClick");
        }
        
        void TalkerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                Console.WriteLine("正在关闭窗口工作模式");
                if (tip != null)
                    tip.Close();
                if (orderForm != null)
                    orderForm.Close();
                if (timer1 != null)
                {
                    timer1.Dispose();
                    timer1.Enabled = false;
                }
                if (TopTimer != null)
                {
                    TopTimer.Dispose();
                    TopTimer.Enabled = false;
                }
                TopTimer = null;
                timer1 = null;
                orderForm = null;
                StopTime();
                if (UtilHelper.DEBUG)
                    MuchInfo.Logs.MILog.Info("正在退出聊天辅助====> 用户=" + WorkProcess.Alias);
            }
            catch
            {
            }
            finally {
                if (CmdCallBack != null)
                    CmdCallBack.BeginInvoke(this, TalkerState.Closed, this, null, null);
            }
        }
       
        void TalkerForm_Load(object sender, EventArgs e)
        {
            lblTitle.Text = Proc.Alias;
            State = TalkerState.Display;
            InitLocation(); 
            try
            {
                RefreshTimout = int.Parse(System.Configuration.ConfigurationManager.AppSettings["RefreshTimout"]);
                if (RefreshTimout <= 50)
                    RefreshTimout = 50;
            }
            catch { }
            timer1.Interval = RefreshTimout;
            timer1.Enabled = true;
            isTop = true;
            orderForm.Show();
            this.TopMost = true;
            orderForm.TopMost = this.TopMost;
            WindowControl.SetForegroundWindow(orderForm.Handle);
            WindowControl.SetForegroundWindow(Handle);
            helper.SetForegroundMainWindow();
            StartTime(2000);
           
        }
        #endregion

        void TopTimer_Tick(object sender, EventArgs e)
        {
            
        }

        #region 接口
        public void SetWinState(TalkerState state)
        {
            if (state == TalkerState.Hidden)
            {
                HideWin();
            }
            else if (state == TalkerState.Display)
            {
                ShowWin();
            }
        }

        public void SetCustomerState(TalkerState state)
        {
            CustoemrState = state;
            switch (state)
            {
                case TalkerState.AutoReply:
                    {
                        break;
                    }
            }
        }

        public CommandCallBack CmdCallBack { get; set; }
        #endregion

        #region 设置焦点

        void SetFoucus()
        {
            try
            {
                switch (State)
                {
                    case TalkerState.Hidden:
                        {
                            break;
                        }
                    case TalkerState.Closed:
                        {
                            break;
                        }
                    default:
                        {
                            lock (this)
                            {
                                IntPtr intptr = WindowControl.GetForegroundWindow();
                                IntPtr intptrFocus = WindowControl.GetFocus();
                                if (hWnds.Count > 20)
                                {
                                    hWnds.RemoveRange(5, 10);
                                }
                                hWnds.Insert(0, intptr);
                                if (intptr == helper.HandleWinForm)
                                {
                                    if (!isTop)
                                    {
                                        WindowControl.SetForegroundWindow(orderForm.Handle);
                                        WindowControl.SetForegroundWindow(Handle);
                                        hWnds.Insert(0, orderForm.Handle);
                                        hWnds.Insert(0, Handle);
                                        this.TopMost = true;
                                            this.TopMost = false;
                                        orderForm.TopMost = true;
                                            orderForm.TopMost = false;
                                            Console.WriteLine("置前");
                                            helper.SetForegroundMainWindow();
                                        
                                        isTop = true;
                                    }

                                }
                                else
                                {
                                    if (this != null && orderForm != null & intptr != orderForm.Handle && intptr != this.Handle)
                                    {
                                        isTop = false;
                                        if (this.TopMost)
                                            this.TopMost = false;
                                        if (orderForm.TopMost)
                                            orderForm.TopMost = false;
                                    }
                                    else
                                    {
                                        
                                    }
                                }
                            }
                            break;
                        }
                }
            }
            catch { }
        }

        #endregion

        #region 初始化位置
        void InitLocation()
        {
            WindowControl.RECT rect;
            helper.MainRect(out rect);
            int cx;
            int cy;
            bool isMax = WindowControl.IsZoomed(helper.HandleWinForm);
            if (isMax)
            {
                cx = this.ScreemWidth - UtilHelper.MAX_MSG_WIDTH;
                cy = ScreemHeight - UtilHelper.MAX_ORDER_HEIGHT;
                WindowControl.ShowWindowAsync(helper.HandleWinForm, WindowControl.SW_RESTORE);
                WindowControl.SetWindowPos(helper.HandleWinForm, (int)this.Handle, 0, 0, cx, cy, 0);
            }

            cx = rect.Right - rect.Left;
            cy = rect.Bottom - rect.Top;

            int posX = (this.ScreemWidth - (UtilHelper.MAX_MSG_WIDTH + cx)) / 2;
            int posY = (this.ScreemHeight - (UtilHelper.MAX_ORDER_HEIGHT + cy)) / 2;
            
            if (rect.Right == 0 && rect.Top == 0 && rect.Left == 0 && rect.Bottom == 0)
            {
                return;
            }

            if (ScreemWidth - cx < UtilHelper.MIN_MSG_WIDTH)
            {
                this.Width = UtilHelper.MAX_MSG_WIDTH;
            }
            else if (ScreemWidth - cx > UtilHelper.MAX_MSG_WIDTH)
            {
                this.Width = UtilHelper.MAX_MSG_WIDTH;
            }
            else
            {
                this.Width = ScreemWidth - cx;
            }

            this.Height = (rect.Bottom - rect.Top) + UtilHelper.MAX_ORDER_HEIGHT;
            this.Location = new Point(cx, rect.Top);
            orderForm.SetLocation(rect.Left, rect.Bottom, cx, ScreemHeight - cy);
        }
        void MoveWindow()
        {
            
        }

        void SetLocation(int x, int y, int w, int h)
        {
            try
            {
                if (isResize) {
                    return;
                }
                if (this.Width == w && this.Height == h && this.Location.X == x && this.Location.Y == y)
                {
                    return;
                }
                lock (this)
                {
                    bool isChanage = false;
                    if (x != Location.X || y != Location.Y)
                    {
                        isChanage = true;
                        this.Location = new Point(x, y);
                        MoveWindow();
                    }

                    if (this.Width != w && w < UtilHelper.MIN_MSG_WIDTH)
                    {
                        this.Width = UtilHelper.MIN_MSG_WIDTH;
                        isChanage = true;
                    }
                    else if (this.Width != w && w > UtilHelper.MAX_MSG_WIDTH)
                    {
                    }
                    else if (this.Width != w)
                    {
                        this.Width = w;
                        isChanage = true;
                    }
                    if (this.Height != h)
                    {
                        this.Height = h;
                        isChanage = true;
                    }

                    if (isChanage)
                    {
                        this.Update();
                    }
                }
            }
            catch
            {
            }
        }

        void SetLocation(WindowControl.RECT rect)
        {
            SetLocation(rect.Right, rect.Top, this.ScreemWidth - rect.Right, ScreemHeight);
        }
        const int SWP_SHOWWINDOW = 64;
        void SetLocation()
        {
            if (!WindowControl.IsWindowVisible(helper.HandleWinForm))
            {
                this.Close();
                return;
            }

            WindowControl.RECT rect;
            helper.MainRect(out rect);
            bool isMax = WindowControl.IsZoomed(helper.HandleWinForm);
            if (isMax)
            {
                int cx = this.ScreemWidth - UtilHelper.MAX_MSG_WIDTH;
                int cy = ScreemHeight - UtilHelper.MAX_ORDER_HEIGHT;
                WindowControl.ShowWindowAsync(helper.HandleWinForm, WindowControl.SW_RESTORE);
                WindowControl.SetWindowPos(helper.HandleWinForm, (int)this.Handle, 0, 0, cx, cy, SWP_SHOWWINDOW);
                WindowControl.ShowWindowAsync(helper.HandleWinForm, SWP_SHOWWINDOW);
            }
            if (WindowControl.IsIconic(helper.HandleWinForm))
            {
                if (Visible)
                {
                    Visible = false;
                    orderForm.Visible = false;
                }
                return;
            }
            else
            {
                if (!this.Visible)
                {
                    this.Visible = true;
                    orderForm.Visible = true;
                }
            }

            if (rect.Right == 0 && rect.Top == 0 && rect.Left == 0 && rect.Bottom == 0)
            {
                this.Close();
                return;
            }

            orderForm.SetLocation(rect.Left, rect.Bottom, rect.Right - rect.Left, ScreemHeight - (rect.Bottom - rect.Top));
            SetLocation(rect.Right, rect.Top, this.ScreemWidth - rect.Right, (rect.Bottom - rect.Top) + UtilHelper.MAX_ORDER_HEIGHT);
        }

        #endregion

        #region 事件处理
        void SaveSendHandler(object sender, MessageBody msgBody)
        {
            try
            {
                if (DataFactory.SystemConfig.SelfLearn)
                {
                    lock (Caches)
                    {
                        if (msgBody.SendName.Equals(this.Proc.Alias))
                        {
                            int count = Caches.Count;
                            string word = "";
                            if (count > 0)
                            {
                                KeyValuePair<string, MessageBody> temp1 = Caches.ElementAt(count - 1);
                                if (!temp1.Value.SendName.Equals(Proc.Alias))
                                {
                                    word = temp1.Value.Content;
                                    if (!string.IsNullOrEmpty(word)) {
                                        word = UtilHelper.SplitMsg(word);
                                    }
                                }
                            }
                            var ds = from temp in DataFactory.ChatRecords.Records where temp.Text.Equals(msgBody.Content) select temp;
                            Record record = ds.FirstOrDefault();
                            if (record != null)
                            {
                                if (string.IsNullOrEmpty(word))
                                {
                                    return;
                                }
                                if (string.IsNullOrEmpty(record.Words))
                                    record.Words += word;
                                else
                                    record.Words += "," + word;
                            }
                            else
                            {
                                DataFactory.ChatRecords.Records.Add(new Record()
                                {
                                    DateType = DataType.Send,
                                    Words = word,
                                    Text = msgBody.Content,
                                    Name = msgBody.SendName,
                                    Time = msgBody.MsgTime
                                });
                            }
                        }
                        else
                        {
                            Caches.Add(msgBody.MsgTime, msgBody);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if(UtilHelper.DEBUG)
                    MuchInfo.Logs.MILog.Debug("SaveSendHandler", ex);
            }
        }
        
        void BodyHandler(object sender, MessageBody msgBody)
        {
            try
            {
                if (BorBodyHandler != null)
                    BorBodyHandler.BeginInvoke(sender, msgBody, null, null);
                Console.WriteLine("收到内容:" + msgBody.Content);
                SaveHandler.BeginInvoke(sender, msgBody, null, null);
            }
            catch { }
        }

        private void btnHide_Click(object sender, EventArgs e)
        {
            this.HideWin();
        }
        int i = 0;
        bool isTop = false;
        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                switch (State)
                {
                    case TalkerState.Hidden:

                        break;
                    case TalkerState.Closed:
                        {
                            break;
                        }
                    default:
                        {
                            SetLocation();
                            SetFoucus();
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                MuchInfo.Logs.MILog.Warn("移动窗口", ex);
            }
        }


        #endregion

        bool focus = true;
        internal void SetActivated() {
            if (hWnds.IndexOf(helper.HandleWinForm) > 2 || hWnds.IndexOf(helper.HandleWinForm) < 0)
            {
                isTop = false;
                helper.SetForegroundMainWindow();
            }
        }
       
        private void TalkerForm_Activated(object sender, EventArgs e)
        {
            if (hWnds.IndexOf(helper.HandleWinForm) > 2 || hWnds.IndexOf(helper.HandleWinForm) < 0)
            {
                helper.SetForegroundMainWindow();
            }
        }
    }
}